package com.hooya.fa.eu.biz.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.hooya.fa.eu.biz.dao.entity.StkOrigDataCollect;
import com.hooya.fa.eu.biz.dao.entity.dto.*;
import com.hooya.fa.eu.biz.dao.mapper.StkOrigDataCollectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class CommonService {

    @Autowired
    private StkOrigDataCollectMapper stkOrigdataCollectMapper;


    //数据校验部分
    public void dataVerificationB2b(List<B2bDataDTO> data) {
        // 检查每个cpbh组中的price值是否唯一
        Map<String, Set<BigDecimal>> priceCountByCpbh = new HashMap<>();

        for (B2bDataDTO item : data) {
            String cpbh = item.getCpbh();
            BigDecimal price = item.getPrice();

            if (cpbh != null) {
                priceCountByCpbh.computeIfAbsent(cpbh, k -> new HashSet<>());
                priceCountByCpbh.get(cpbh).add(price);
            }
        }

        // 检查是否有cpbh组中的price值不唯一
        for (Map.Entry<String, Set<BigDecimal>> entry : priceCountByCpbh.entrySet()) {
            Set<BigDecimal> prices = entry.getValue();
            // 如果一个cpbh组中有多个不同的price值（不包括null），或者有一个price值和一个null值
            if (prices.size() > 1 || (prices.size() == 1 && prices.contains(null))) {
                throw new RuntimeException("每个cpbh组中的price值应该唯一，但cpbh: " + entry.getKey() + " 有多个不同的price值");
            }
        }

        // 检查是否有价格为空的数据
        List<B2bDataDTO> noPriceData = data.stream().filter(item -> item.getPrice() == null).collect(Collectors.toList());

        if (!noPriceData.isEmpty()) {
            throw new RuntimeException("存在没有价格的数据，数量: " + noPriceData.size());
        }

        log.info("数据验证通过");
    }

    public void dataVerificationB2c(List<B2cDataDTO> data) {
        List<B2cDataDTO> noPriceData = data.stream()
                .filter(dto -> (dto.getFromcompany() != null && (dto.getFromcompany().startsWith("costway") || dto.getFromcompany().startsWith("fds")))
                        && dto.getPrice() == null
                        && dto.getBelongs() != null && dto.getBelongs().startsWith("costway"))
                .collect(Collectors.toList());

        if (!noPriceData.isEmpty()) {
            log.error("存在没有价格数据，数量: {} 数据为：{}", noPriceData.size(), noPriceData);
            //  TODO -- 后期删除
//            throw new RuntimeException("存在没有价格的数据，数量: " + noPriceData.size());
        }

        log.info("数据验证通过");
    }

    public void dataVerificationBs(List<BsDataDTO> data) {
        List<BsDataDTO> noPriceData = data.stream().filter(dto -> dto.getPrice() == null && dto.getBelongs() != null && dto.getBelongs().startsWith("costway")).collect(Collectors.toList());

        if (!noPriceData.isEmpty()) {
            log.error("Bs的异常数据数量为：{} ， 异常数据为：{}", noPriceData.size(), noPriceData);
            //TODO -- 后续删除
//            throw new RuntimeException("存在没有价格的数据，数量: " + noPriceData.size());
        }
        log.info("数据验证通过");
    }

    public void dataVerificationCg(List<CGDataDTO> data) {
        // 验证逻辑：检查是否存在没有价格的记录
        List<CGDataDTO> noPriceCount = data.stream()
                .filter(d -> d.getPrice() == null)
                .collect(Collectors.toList());

        if (!noPriceCount.isEmpty()) {
            log.error("异常数据数量为：{}，异常数据为：{}", noPriceCount.size(), noPriceCount);
            //TODO -- 后续删除
//            throw new RuntimeException("存在没有价格或价格为零的记录，数量: " + noPriceCount);
        }
    }

    public void dataVerificationTh(List<ThDataDTO> data) {
        List<ThDataDTO> noPriceData = data.stream()
                .filter(d -> d.getPrice() == null)
                .collect(Collectors.toList());

        if (!noPriceData.isEmpty()) {
            log.error("存在无价格的数据，数量：{} , 数据{}", noPriceData.size(), noPriceData);
            // TODO -- 后续删除
//            throw new RuntimeException("存在无价格的数据");
        }
    }

    public void dataVerificationZy(List<ZyDataDTO> data) {
        // 验证逻辑：检查是否存在没有价格的记录
        List<ZyDataDTO> noPriceCount = data.stream()
                .filter(d -> d.getPrice() == null)
                .collect(Collectors.toList());

        if (!noPriceCount.isEmpty()) {
            log.error("存在没有价格的记录，数量: {} , 数据{}", noPriceCount.size(), noPriceCount);
            // TODO -- 后续删除
//            throw new RuntimeException("存在没有价格的记录，数量: " + noPriceCount);
        }
    }

    /**
     * 批量插入数据
     */
    public void batchInsert(List<StkOrigDataCollect> records) {
        if (records.isEmpty()) {
            log.info("批量插入数据为空");
            return;
        }
        try {
            //TODO -- 后续放开
//            stkOrigdataCollectMapper.insertBatch(records);
            log.info("批量插入数据完成，插入条数：{}", records.size());
        } catch (Exception e) {
            log.error("批量插入数据失败", e);
            throw new RuntimeException("批量插入数据失败", e);
        }
    }

    /**
     * 处理日期 -- 后续可删
     */
    public Map<String, String> dateChange(String start) {
        Map<String, String> result = new HashMap<>();
        LocalDate startDate = LocalDate.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate nextStartDate = startDate.plusMonths(1);
        LocalDate endDate = nextStartDate.minusDays(1);

        result.put("currMonthStart", start);
        result.put("nextMonthStart", nextStartDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        result.put("currMonthEnd", endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

        return result;
    }

    // 数据转换方法部分
    public List<StkOrigDataCollect> convertB2bToStkOrigDataCollect(List<B2bDataDTO> dataList) {
        return dataList.stream().map(dto -> {
            StkOrigDataCollect record = convertBaseStkOrignDataCollect(dto.getCpbh(), dto.getSl(), dto.getDate(), dto.getPlace());
            record.setSeller(dto.getSeller());
            record.setBuyer(dto.getBuyer());
            record.setFromcountry(dto.getFromcountry());
            record.setTocountry(dto.getTocountry());
            record.setSheetnumber(dto.getSheetnumber());
            record.setType(dto.getType());
            record.setSellertaxid(dto.getSellertaxid());
            record.setBuyertaxid(dto.getBuyertaxid());
            record.setPrice(dto.getPrice());
            record.setOceanfee(dto.getOceanfee());
            record.setCurrency(dto.getCurrency());
            record.setInvoiceid(dto.get_id());
            record.setBelongs(dto.getBelongs());
            record.setDirection(dto.getDirection());
            record.setInvoicedate(dto.getInvoicedate());
            record.setExportprice(dto.getExportprice());
            record.setInvoiceno(dto.getInvoiceno());
            record.setCreatetime(Date.from(java.time.LocalDateTime.now().atZone(java.time.ZoneId.systemDefault()).toInstant()));
            return record;
        }).collect(Collectors.toList());
    }

    public List<StkOrigDataCollect> convertB2cToStkOrigDataCollect(List<B2cDataDTO> dataList, boolean hasPrice) {

        return dataList.stream().map(dto -> {
            StkOrigDataCollect record = convertBaseStkOrignDataCollect(dto.getCpbh(), dto.getSl(), dto.getDate(), dto.getPlace());
            record.setDirection(dto.getDirection());
            record.setBelongs(dto.getBelongs());
            record.setType(dto.getType());
            record.setSeller(dto.getFromcompany());
            record.setOrderid(dto.getOrderid());
            record.setSheetnumber(dto.getSheetnumber());
            record.setInvoicedate(dto.getInvoicedate());
            if (hasPrice) {
                record.setPrice(dto.getPrice());
                record.setCurrency(dto.getCurrency());
                record.setInvoiceno(dto.getHthm());
            }
            record.setBuyer(dto.getTocompany());
            record.setCreatetime(Date.from(java.time.LocalDateTime.now().atZone(java.time.ZoneId.systemDefault()).toInstant()));
            return record;
        }).collect(Collectors.toList());
    }

    public List<StkOrigDataCollect> convertBsToStkOrigDataCollect(List<BsDataDTO> dataList, boolean hasPrice) {
        return dataList.stream().map(dto -> {
            StkOrigDataCollect record = convertBaseStkOrignDataCollect(dto.getCpbh(), dto.getSl(), dto.getDate(), dto.getPlace());
            record.setDirection(dto.getDirection());
            record.setBelongs(dto.getBelongs());
            record.setType(dto.getType());
            if (hasPrice) {
                record.setInvoicedate(dto.getInvoicedate());
                record.setCurrency(dto.getCurrency());
                record.setPrice(dto.getPrice());
            }
            record.setCreatetime(Date.from(java.time.LocalDateTime.now().atZone(java.time.ZoneId.systemDefault()).toInstant()));
            return record;
        }).collect(Collectors.toList());
    }

    public List<StkOrigDataCollect> convertGgToStkOrigDataCollect(List<CGDataDTO> dataList) {
        List<StkOrigDataCollect> result = new ArrayList<>();
        for (CGDataDTO data : dataList) {
            StkOrigDataCollect record = new StkOrigDataCollect();
            convertStkOrignDataCollect(record, data.getCpbh(), data.getHthm(), data.getSl(), data.getDate(), data.getPlace(), data.getDirection(), data.getBelongs());
            record.setSheetnumber(data.getSheetnumber());
            record.setType(data.getType());
            record.setInvoicedate(data.getInvoicedate());
            record.setPrice(data.getPrice());
            record.setCurrency(data.getCurrency());
            record.setCreatetime(Date.from(java.time.LocalDateTime.now().atZone(java.time.ZoneId.systemDefault()).toInstant()));
            result.add(record);
        }
        return result;
    }

    public List<StkOrigDataCollect> convertThToStkOrigDataCollect(List<ThDataDTO> dataList) {
        List<StkOrigDataCollect> result = new ArrayList<>();
        for (ThDataDTO data : dataList) {
            StkOrigDataCollect record = new StkOrigDataCollect();
            BeanUtil.copyProperties(data, record);
            convertStkOrignDataCollect(record, data.getCpbh(), data.getHthm(), data.getSl(), data.getDate(), data.getPlace(), data.getDirection(), data.getBelongs());
            record.setType(data.getType());
            record.setSeller(data.getFromcompany());
            record.setBuyer(data.getTocompany());
            record.setFromcountry(data.getFromcountry());
            record.setTocountry(data.getTocountry());
            record.setSheetnumber(data.getSheetnumber());
            record.setInvoiceno(data.getHthm());
            record.setOceanfee(data.getOceanfee());
            record.setInvoiceid(data.get_id());
            record.setInvoicedate(data.getInvoicedate());
            record.setCurrency(data.getCurrency());
            record.setPrice(data.getPrice());
            record.setExportprice(data.getExportprice());
            record.setCreatetime(Date.from(java.time.LocalDateTime.now().atZone(java.time.ZoneId.systemDefault()).toInstant()));
            result.add(record);
        }
        return result;
    }

    public List<StkOrigDataCollect> convertZyToStkOrigDataCollect(List<ZyDataDTO> dataList) {
        List<StkOrigDataCollect> result = new ArrayList<>();
        for (ZyDataDTO data : dataList) {
            StkOrigDataCollect record = new StkOrigDataCollect();
            BeanUtil.copyProperties(data, record);
            convertStkOrignDataCollect(record, data.getCpbh(), data.getHthm(), data.getSl(), data.getDate(), data.getPlace(), data.getDirection(), data.getBelongs());
            record.setType(data.getType());
            record.setSeller(data.getFromcompany());
            record.setBuyer(data.getTocompany());
            record.setFromcountry(data.getFromcountry());
            record.setTocountry(data.getTocountry());
            record.setSheetnumber(data.getSheetnumber());
            record.setInvoiceno(data.getHthm());
            record.setOceanfee(data.getOceanfee());
            record.setInvoiceid(data.get_id());
            record.setInvoicedate(data.getInvoicedate());
            record.setCurrency(data.getCurrency());
            record.setPrice(data.getPrice());
            record.setExportprice(data.getExportprice());
            record.setCreatetime(Date.from(java.time.LocalDateTime.now().atZone(java.time.ZoneId.systemDefault()).toInstant()));
            result.add(record);
        }
        return result;
    }

    /**
     * 提取方法的公共部分--基础转换
     */
    private StkOrigDataCollect convertBaseStkOrignDataCollect(String cpbh, Integer sl, Date date, String place) {
        StkOrigDataCollect record = new StkOrigDataCollect();
        record.setId(UUID.randomUUID().toString().replace("-", "").toLowerCase().toLowerCase());
        record.setSku(cpbh);
        record.setQty(sl);
        record.setInoutdate(date);
        record.setWhid(place);
        return record;
    }

    private void convertStkOrignDataCollect(StkOrigDataCollect record, String cpbh, String hthm, Integer sl, Date date, String place, String direction, String belongs) {
        record.setId(UUID.randomUUID().toString().replace("-", "").toLowerCase());
        record.setSku(cpbh);
        record.setInvoiceno(hthm);
        record.setQty(sl);
        record.setInoutdate(date);
        record.setWhid(place);
        record.setDirection(direction);
        record.setBelongs(belongs);
    }


}
